﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;


namespace BaccaratRally.DataKernel.Entity
{
    [AttributeUsage(AttributeTargets.Property)]
    public class SqlFieldAttribute : Attribute
    {
        public SqlFieldAttribute(string _name) { Name = _name; }
        public SqlFieldAttribute(string _name, bool _isNullable) { Name = _name; IsNullable = _isNullable; }
        public SqlFieldAttribute(string _name, bool _isPrimaryKey, bool _isUnique, bool _isNullable, bool _readyOnly) { Name = _name; IsPrimaryKey = _isPrimaryKey; IsUnique = _isUnique; IsNullable = _isNullable; ReadyOnly = _readyOnly; }

        public string Name { get; set; }
        public bool IsNullable { get; set; }
        public bool IsPrimaryKey { get; set; }
        public bool IsUnique { get; set; }
        public bool ReadyOnly { get; set; }
    }

    [AttributeUsage(AttributeTargets.Class)]
    public class SqlTableAttribute : Attribute
    {
        public SqlTableAttribute(string _name) { Name = _name; }
        public string Name { get; set; }
    }

    public class SqlMappingException : Exception
    {
        public SqlMappingException(string message) : base(message) { }
    }

    public abstract class EntityBase
    {
        internal abstract void ReBuildInstance(SqlDataReader reader);
        internal abstract SqlParameter[] BuildInsertParamter();
        internal abstract SqlParameter[] BuildUpdateParamter();
        internal abstract string GetInsertCommandText();
        internal abstract string GetUpdateCommandText();

        /// <summary>
        /// 从SqlDataReader的数据字段取值
        /// </summary>
        /// <typeparam name="T">值的泛型类别</typeparam>
        /// <param name="reader">传入的SqlDataReader</param>
        /// <param name="field">数据字段</param>
        /// <returns>取值结果</returns>
        protected internal T GetReaderValue<T>(SqlDataReader reader, string field)
        {
            T result = default(T);
            int pos = reader.GetOrdinal(field);
            if (pos < 0)
                return result;
            if (reader.IsDBNull(pos))
                return result;

            try
            {
                result = (T)Convert.ChangeType(reader.GetValue(pos), typeof(T));
            }
            catch (InvalidCastException ex)
            {
            }
            catch
            {
                throw;
            }

            return result;
        }

        /// <summary>
        /// 创建实体实例
        /// </summary>
        /// <typeparam name="T">实体泛型类别</typeparam>
        /// <param name="reader">从SqlDataReader创建实体</param>
        /// <returns>数据实体</returns>
        public static T CreateEntity<T>(SqlDataReader reader) where T : EntityBase
        {
            T entity = Activator.CreateInstance<T>();
            entity.ReBuildInstance(reader);
            return entity;
        }
    }
}
